package com.hsxc.cdz.monitor.executor;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hsxc.cdz.base.util.Constants;
import com.hsxc.cdz.base.util.TimeFormatter;
import com.hsxc.cdz.mgmt.GlobalManager;
import com.hsxc.cdz.monitor.FSM.CachePile;
import com.hsxc.cdz.monitor.bean.MessageNew;
import com.hsxc.cdz.monitor.bean.server.v1_33.ChargeCeaseSerMsg;
import com.hsxc.cdz.monitor.bean.server.v1_33.ChargeSerMsg;
import com.hsxc.cdz.monitor.bean.server.v1_33.IPSettingSerMsg;
import com.hsxc.cdz.monitor.bean.server.v1_33.QRCSettingSerMsg;
import com.hsxc.cdz.monitor.bean.server.v1_33.RateSettingSerMsg;
import com.hsxc.cdz.monitor.bean.server.v1_33.ReserveCeaseSerMsg;
import com.hsxc.cdz.monitor.bean.server.v1_33.ReserveSerMsg;
import com.hsxc.cdz.monitor.bean.server.v1_33.TimeSerMsg;

import io.netty.channel.Channel;

/**
 * @author 作者 : 陈钊
 * @version 创建时间：2016年9月22日 上午10:21:23 类说明：
 */
public class ServerExecutorNew {
	public static final int SUCCESS = 0;
	public static final int ERR_DEVICE = -1;
	public static final int FAILURE = 1;
	private static Logger logger = LoggerFactory.getLogger(ServerExecutorNew.class);

	/**
	 * 服务器下发充电开始指令 for 直流桩
	 * 
	 * @param chargePort
	 *            充电口号：0 A口，1 B口。
	 * @param startWay
	 *            启动方式：0 即时充电，1 定时充电。
	 * @param ctrlWay
	 *            控制方式 ：0 BMS充电，1 盲充。
	 * @param stopWay
	 *            停止充电的方式 ： 1 电量控制充电 ，2 时间控制充电 ，3 金额控制充电 ，4充满为止。
	 * @param limitData
	 *            开启限制数据：不同充电模式下停机条件。
	 * @param startTime
	 *            开始充电时间。
	 * @param cardNum
	 *            用户卡号。
	 * @param pileAddress
	 *            充电桩设备地址。
	 * @param operatorNO
	 *            运营商编号。
	 * @param chargeDataInterval
	 *            充电数据上传间隔
	 * @param batteryDataInteval
	 *            电池数据上传间隔
	 * @param protocol
	 *            协议
	 * @return 返回值：-1无连接，0正常执行，1命令执行失败。
	 * 
	 */
	public static int startCharge_zhiliu(int chargePort, int startWay, int ctrlWay, int stopWay, double limitData,
			String startTime, String cardNum, String pileAddress, String operatorNO, int chargeDataInterval,
			int batteryDataInteval, String protocol,int pileType) {
		if (startTime == null || cardNum == null || pileAddress == null || operatorNO == null) {
			return 1;
		}
		ChargeSerMsg startMsg = new ChargeSerMsg();
		startMsg.setChargePort(chargePort);
		int ctrl = 0;
		ctrl = ctrl | (startWay << 7);
		ctrl = ctrl | (ctrlWay << 6);
		ctrl = ctrl | stopWay;
		startMsg.setControll(ctrl);
		startMsg.setLimitData((int) (limitData * 100));
		startMsg.setStartTime(startTime);
		startMsg.setCardNum(cardNum);

		// 设置直流桩的报文信息
		startMsg.setChargeDataInterval(chargeDataInterval);
		startMsg.setBatteryInterval(batteryDataInteval);

		MessageNew message = new MessageNew();
		message.setIsOpen(Constants.START_UP);
		message.setContentLength(ChargeSerMsg.length);
		message.setIsRegister(Constants.DID_REGISTER);
		message.setResponse(Constants.RESPONSE_NOMAL);
		message.setOperator(operatorNO);
		message.setAddress(pileAddress);
		message.setFrame(Constants.SERVER_SEND_START);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		message.setLineNum(sdf.format(new Date()));
		message.setContent(startMsg.getBytesFromMessage());

		CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
		if (cachePile != null) {
			Channel channel = cachePile.getChannel();
			if (channel != null) {
				channel.writeAndFlush(message);
				return SUCCESS;
			} else {
				return FAILURE;
			}
		} else {
			return ERR_DEVICE;
		}
	}

	/**
	 * 
	 * @param startWay
	 *            启动方式：0 即时充电，1 定时充电。
	 * @param ctrlWay
	 *            控制方式 ：0 BMS充电，1 盲充。
	 * @param stopWay
	 *            停止充电的方式 ： 1 电量控制充电 ，2 时间控制充电 ，3 金额控制充电 ，4充满为止。
	 * @param ChargePort
	 *            充电口号 ：0 A口，1 B口。
	 * @param cardNum
	 *            用户卡号。
	 * @param pileAddress
	 *            充电桩设备地址。
	 * @param operatorNO
	 *            运营商编号。
	 * @return 返回值：-1无连接，0正常执行，1命令执行失败。
	 * 
	 */
	public static int stopCharge(int startWay, int ctrlWay, int stopWay, int ChargePort, String cardNum,
			String pileAddress, String operatorNO, String protocol, int pileType) {
		if (cardNum == null || pileAddress == null || operatorNO == null) {
			// logger.error("TRANS: sth is null, carNum={}, pileAddress={},
			// operatorNO={}", cardNum, pileAddress, operatorNO);
			// logger.error("TRANS:cardNum:{},pileAddress:{},operatorNo:{}",
			// cardNum,pileAddress,operatorNO);
			return 1;
		}
		ChargeCeaseSerMsg stopMessage = new ChargeCeaseSerMsg();
		stopMessage.setPort(ChargePort);
		int ctrl = 0;
		ctrl = ctrl | (startWay << 7);
		ctrl = ctrl | (ctrlWay << 6);
		ctrl = ctrl | stopWay;
		stopMessage.setControll(ctrl);
		stopMessage.setCardNum(cardNum);

		MessageNew message = new MessageNew();
		message.setIsOpen(Constants.START_UP);
		message.setContentLength(ChargeCeaseSerMsg.length);
		message.setIsRegister(Constants.DID_REGISTER);
		message.setResponse(Constants.RESPONSE_NOMAL);
		message.setOperator(operatorNO);
		message.setAddress(pileAddress);
		message.setFrame(Constants.SERVER_SEND_STOP);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		message.setLineNum(sdf.format(new Date()));
		message.setPileType(pileType);
		message.setProtocolVersion(protocol);

		message.setContent(stopMessage.getBytesFromMessage());

		CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
		if (cachePile != null) {
			Channel channel = cachePile.getChannel();
			if (channel != null) {
				channel.writeAndFlush(message);
				logger.info("TRANS: send stop charge command to pile {} ok.", pileAddress);
				return SUCCESS;
			} else {
				logger.error("TRANS:get channel of pile {} as null", cachePile.getAddress());
				return FAILURE;
			}
		} else {
			logger.error("TRANS:Can't find pile {}", pileAddress);
			return ERR_DEVICE;
		}
	}

	/**
	 * 
	 * 服务器下发预约
	 * 
	 * @param chargePort
	 *            充电口号 ：0 A口，1 B口。
	 * @param cardNum
	 *            用户卡号。
	 * @param pileAddress
	 *            充电桩设备地址。
	 * @param operatorNO
	 *            运营商编号。
	 * @param duration
	 *            预约时长。
	 * @return 返回值：-1无连接，0正常执行，1命令执行失败，2参数有误。
	 * 
	 */
	public static int reserve(int chargePort, String cardNum, String pileAddress, String operatorNO, int duration,
			String protocol, int pileType) {
		if (cardNum == null || pileAddress == null || operatorNO == null) {
			return FAILURE;
		}
		CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
		if (cachePile == null) {
			return ERR_DEVICE;
		}

		// 设置预约报文信息
		ReserveSerMsg reserveMessage = new ReserveSerMsg();
		reserveMessage.setChargePort(chargePort);
		reserveMessage.setCardNum(cardNum);
		reserveMessage.setDoration(duration);

		// 设置发送报文信息
		MessageNew message = new MessageNew();
		message.setIsOpen(Constants.START_UP);
		message.setContentLength(ReserveSerMsg.length);
		message.setIsRegister(Constants.DID_REGISTER);
		message.setResponse(Constants.RESPONSE_NOMAL);
		message.setOperator(operatorNO);
		message.setAddress(pileAddress);
		message.setFrame(Constants.SERVER_SEND_ORDER);
		message.setLineNum(TimeFormatter.toTimeYear());
		message.setContent(reserveMessage.getBytesFromMessage());
		message.setPileType(pileType);
		message.setProtocolVersion(protocol);
		// 获取通道发送报文
		Channel channel = cachePile.getChannel();
		if (channel != null) {
			channel.writeAndFlush(message);
			return SUCCESS;
		} else {
			return FAILURE;
		}
	}

	/**
	 * 
	 * 服务器下发取消预约
	 * 
	 * @param pileAddress
	 *            ：充电桩设备地址
	 * @param chargePort
	 *            ：充电口号
	 * @param cardNum
	 *            ：卡号
	 * @return int： 0 命令执行正常 ，1 未找到充电桩，-1 命令执行失败
	 */
	public int cancelReserve(String pileAddress, int chargePort, String cardNum, String protocol, int pileType) {
		if (cardNum == null || pileAddress == null) {
			return 1;
		}
		// 设置取消预约报文业务信息
		ReserveCeaseSerMsg reserCeaserMsg = new ReserveCeaseSerMsg();
		reserCeaserMsg.setPort(chargePort);
		reserCeaserMsg.setCardNum(cardNum);

		MessageNew message = new MessageNew();
		message.setIsOpen(Constants.START_UP);
		message.setIsRegister(Constants.DID_REGISTER);
		message.setAddress(pileAddress);
		message.setContent(reserCeaserMsg.getBytesFromMessage());
		message.setContentLength(ReserveCeaseSerMsg.length);
		message.setFrame(Constants.SERVER_SEND_STOP_ORDER);
		message.setLineNum(TimeFormatter.toTimeYear());
		message.setResponse(Constants.RESPONSE_NOMAL);
		message.setPileType(pileType);
		message.setProtocolVersion(protocol);
		CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
		if (cachePile != null) {
			message.setOperator(cachePile.getOperator());
			Channel channel = cachePile.getChannel();
			if (channel != null) {
				channel.writeAndFlush(message);
				return SUCCESS;
			} else {
				return FAILURE;
			}
		} else {
			return ERR_DEVICE;
		}
	}

	/**
	 * 
	 * 重启命令
	 * 
	 * @param pileAddress
	 *            充电桩地址
	 * @return
	 */
	public int restart(String pileAddress, String protocol, int pileType) {
		if (pileAddress == null) {
			return ERR_DEVICE;
		}

		MessageNew message = new MessageNew();
		message.setIsOpen(Constants.START_UP);
		message.setIsRegister(Constants.DID_REGISTER);
		message.setAddress(pileAddress);
		message.setContent(null);
		message.setFrame(Constants.SERVER_SEND_RESTART);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		message.setLineNum(sdf.format(new Date()));
		message.setResponse(Constants.RESPONSE_NOMAL);
		message.setPileType(pileType);
		message.setProtocolVersion(protocol);
		CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
		if (cachePile != null) {
			message.setOperator(cachePile.getOperator());
			Channel channel = cachePile.getChannel();
			if (channel != null) {
				channel.writeAndFlush(message);
				return SUCCESS;
			} else {
				return FAILURE;
			}
		} else {
			return -1;
		}
	}

	/**
	 * 对时设置
	 * @param currentTime
	 * @param pileAddress
	 * @param protocol
	 * @param pileType
	 * @return
	 */
	public int checkTime(String currentTime, String pileAddress, String protocol, int pileType) {
		TimeSerMsg timeSerMsg = new TimeSerMsg();
		timeSerMsg.setContext(currentTime);
		MessageNew message = new MessageNew();
		message.setIsOpen(Constants.START_UP);
		message.setIsRegister(Constants.DID_REGISTER);
		message.setAddress(pileAddress);
		message.setContent(timeSerMsg.getBytesFromMessage());
		message.setContentLength(TimeSerMsg.length);
		message.setFrame(Constants.SERVER_SEND_CHECKTIME);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		message.setLineNum(sdf.format(new Date()));
		message.setResponse(Constants.RESPONSE_NOMAL);
		message.setPileType(pileType);
		message.setProtocolVersion(protocol);
		CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
		if (cachePile != null) {
			message.setOperator(cachePile.getOperator());
			Channel channel = cachePile.getChannel();
			if (channel != null) {
				channel.writeAndFlush(message);
				return SUCCESS;
			} else {
				return FAILURE;
			}
		} else {
			return ERR_DEVICE;
		}
	}

	/**
	 * 查询服务器ip
	 * 
	 * @param pileAddress
	 *            充电桩设备地址
	 * @param protocol
	 *            协议版本
	 * @return
	 */
	public int queryIP(String pileAddress, String protocol, int pileType) {
		if (pileAddress == null) {
			return ERR_DEVICE;
		}
		MessageNew message = new MessageNew();
		message.setIsOpen(Constants.START_UP);
		message.setIsRegister(Constants.DID_REGISTER);
		message.setAddress(pileAddress);
		message.setContent(null);
		message.setFrame(Constants.SERVER_SEND_RESTART);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		message.setLineNum(sdf.format(new Date()));
		message.setResponse(Constants.RESPONSE_NOMAL);
		message.setPileType(pileType);
		message.setProtocolVersion(protocol);
		CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
		if (cachePile != null) {
			message.setOperator(cachePile.getOperator());
			Channel channel = cachePile.getChannel();
			if (channel != null) {
				channel.writeAndFlush(message);
				return SUCCESS;
			} else {
				return FAILURE;
			}
		} else {
			return ERR_DEVICE;
		}
	}

	/**
	 * 设置服务器ip
	 * 
	 * @param type
	 *            生效类型 ：0 立即生效，1延时生效
	 * @param time
	 *            生效时间：格式为 yyyyMMddHHmmss
	 * @param firstIP
	 *            一级备用ip地址
	 * @param firstPort
	 *            一级备用ip端口口号
	 * @param secondIP
	 *            一级备用ip地址
	 * @param secondPort
	 *            一级备用ip端口口号
	 * @param pileAddress
	 *            充电桩设备地址
	 * @return 0 命令执行正常 ，1 未找到充电桩，-1 命令执行失败
	 * 
	 */
	public int setIP(int type, String time, int firstIP, int firstPort, int secondIP, int secondPort,
			String pileAddress, String protocol, int pileType) {
		IPSettingSerMsg ipSetting = new IPSettingSerMsg();
		ipSetting.setType(type);
		ipSetting.setTime(time);
		ipSetting.setFirstIP(firstIP);
		ipSetting.setFirstPort(firstPort);
		ipSetting.setSecondIP(secondIP);
		ipSetting.setSecondPort(secondPort);

		MessageNew message = new MessageNew();
		message.setIsOpen(Constants.START_UP);
		message.setIsRegister(Constants.DID_REGISTER);
		message.setAddress(pileAddress);
		message.setContent(ipSetting.getBytesFromMessage());
		message.setContentLength(ReserveCeaseSerMsg.length);
		message.setFrame(Constants.SERVER_SEND_FITIP);
		message.setLineNum(TimeFormatter.toTimeYear());
		message.setResponse(Constants.RESPONSE_NOMAL);
		message.setPileType(pileType);
		message.setProtocolVersion(protocol);
		CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
		if (cachePile != null) {
			message.setOperator(cachePile.getOperator());
			Channel channel = cachePile.getChannel();
			if (channel != null) {
				channel.writeAndFlush(message);
				return SUCCESS;
			} else {
				return FAILURE;
			}
		} else {
			return ERR_DEVICE;
		}
	}

	/**
	 * 查询费率
	 * 
	 * @param pileAddress
	 *            设备地址
	 * @return
	 */
	public int queryRate(String pileAddress, String protocol, int pileType) {
		MessageNew message = new MessageNew();
		message.setIsOpen(Constants.START_UP);
		message.setIsRegister(Constants.DID_REGISTER);
		message.setAddress(pileAddress);
		message.setContent(null);
		message.setContentLength(0);
		message.setFrame(Constants.SERVER_SEND_QUERYRATE);
		message.setLineNum(TimeFormatter.toTimeYear());
		message.setResponse(Constants.RESPONSE_NOMAL);
		message.setPileType(pileType);
		message.setProtocolVersion(protocol);
		CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
		if (cachePile != null) {
			message.setOperator(cachePile.getOperator());
			Channel channel = cachePile.getChannel();
			if (channel != null) {
				channel.writeAndFlush(message);
				return SUCCESS;
			} else {
				return FAILURE;
			}
		} else {
			return ERR_DEVICE;
		}
	}

	/**
	 * 设置费率
	 * 
	 * @param oneRate
	 *            一号费率
	 * @param twoRate
	 *            二号费率
	 * @param threeRate
	 *            三号费率
	 * @param fourRate
	 *            四号费率
	 * @param serviceFee
	 *            服务费
	 * @param timeRate
	 *            时间点执行费率号
	 * @param pileAddress
	 *            充电桩设备地址
	 * @return
	 */
	public int setRate(double oneRate, double twoRate, double threeRate, double fourRate, double serviceFee,
			String timeRate, String pileAddress, String protocol, int pileType) {
		CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);

		if (cachePile == null) {
			return ERR_DEVICE;
		}
		RateSettingSerMsg rateSetting = new RateSettingSerMsg();
		rateSetting.setOneRate((int) (oneRate * 100));
		rateSetting.setTwoRate((int) (twoRate * 100));
		rateSetting.setThreeRate((int) (threeRate * 100));
		rateSetting.setFourRate((int) (fourRate * 100));
		rateSetting.setServiceFee((int) (serviceFee * 100));
		rateSetting.setTimeRate(timeRate);

		MessageNew message = new MessageNew();
		message.setAddress(cachePile.getAddress());
		message.setContent(rateSetting.getBytesFromMessage());
		message.setContentLength(QRCSettingSerMsg.length);
		message.setFrame(Constants.SERVER_SEND_FITRATE);
		message.setIsOpen(Constants.START_UP);
		message.setIsRegister(Constants.DID_REGISTER);
		message.setLineNum(TimeFormatter.toTimeYear());
		message.setOperator(cachePile.getOperator());
		message.setResponse(Constants.RESPONSE_NOMAL);
		message.setPileType(pileType);
		message.setProtocolVersion(protocol);
		Channel channel = cachePile.getChannel();
		if (channel != null) {
			channel.writeAndFlush(message);
			return SUCCESS;
		} else {
			return FAILURE;
		}
	}

	// 设置二维码
	public static int setQRC(String pileAddress, String qrc, String protocol, int pileType) {
		CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
		if (cachePile == null) {
			return ERR_DEVICE;
		}
		QRCSettingSerMsg qrcSetting = new QRCSettingSerMsg();
		qrcSetting.setData(qrc);
		MessageNew message = new MessageNew();
		message.setAddress(cachePile.getAddress());
		message.setContent(qrcSetting.getBytesFromMessage());
		message.setContentLength(RateSettingSerMsg.length);
		message.setFrame(Constants.SERVER_SEND_QRC);
		message.setIsOpen(Constants.START_UP);
		message.setIsRegister(Constants.DID_REGISTER);
		message.setLineNum(TimeFormatter.toTimeYear());
		message.setOperator(cachePile.getOperator());
		message.setResponse(Constants.RESPONSE_NOMAL);
		message.setPileType(pileType);
		message.setProtocolVersion(protocol);
		Channel channel = cachePile.getChannel();
		if (channel != null) {
			channel.writeAndFlush(message);
			return SUCCESS;
		} else {
			return FAILURE;
		}
	}

}
